import { AxesHelper, BoxGeometry, Vector2, Mesh, MeshLambertMaterial, PCFShadowMap, PerspectiveCamera, PlaneGeometry, Scene, SphereGeometry, SpotLight, WebGLRenderer } from "three"
import Stats from 'stats.js'

// 定义一个场景
const scene = new Scene()
// 透视摄像机
// PerspectiveCamera(FOV, aspectRatio, near, far)
// - FOV  视野角度
// - aspectRatio 长宽比
// - near 近截面
// - far  远截面
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)

// 渲染器
const renderer = new WebGLRenderer({ antialias: true })
// 设置背景色
renderer.setClearColor(0xeeeeee, 1.0)
renderer.setPixelRatio(window.devicePixelRatio)
// 设置渲染器的大小
renderer.setSize(window.innerWidth, window.innerHeight)
// 开启阴影功能
renderer.shadowMap.enabled = true
renderer.shadowMap.type = PCFShadowMap
// 添加到页面
document.body.appendChild( renderer.domElement )

// 添加坐标对象
const axes = new AxesHelper(20)
scene.add(axes)

// 定义一个平面
const planeGeometry = new PlaneGeometry(60, 20, 1, 1)
const planeMaterial = new MeshLambertMaterial({ color: 0xffffff })
const plane = new Mesh(planeGeometry, planeMaterial)

plane.rotation.x = -0.5 * Math.PI
plane.position.x = 15
plane.position.y = 0
plane.position.z = 0
// 平面接收阴影
plane.receiveShadow = true

scene.add(plane)

const geometry = new BoxGeometry(4, 4, 4)
const material = new MeshLambertMaterial({ color: 0xff0000 })
const cube = new Mesh(geometry, material)

cube.position.x = -4
cube.position.y = 3
cube.position.z = 0
// 正方体投射阴影
cube.castShadow = true

scene.add( cube )

const sphereGeometry = new SphereGeometry(4, 20, 20)
const sphereMaterial = new MeshLambertMaterial({ color: 0x7777ff })
const sphere = new Mesh(sphereGeometry, sphereMaterial)
// 定位
sphere.position.x = 20
sphere.position.y = 4
sphere.position.z = 2
// 球产生阴影
sphere.castShadow = true
scene.add(sphere)

// 设置相机位置
camera.position.x = -30
camera.position.y = 40
camera.position.z = 30
// 观测场景中心
camera.lookAt(scene.position)

// 添加光源
const spotLight = new SpotLight(0xffffff)
spotLight.position.set(-40, 60, -10)
// 光源产生阴影
spotLight.castShadow = true
spotLight.shadow.mapSize = new Vector2(1024, 1024)
spotLight.shadow.camera.far = 130
spotLight.shadow.camera.near = 40
scene.add(spotLight)

// 添加场景与相机
renderer.render(scene, camera)

let stats = new Stats()
stats.showPanel( 0 ) // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.dom )

// 动画
let step = 0
function renderScene() {
  stats.update()

  // 正方体转动
  cube.rotation.x += 0.02
  cube.rotation.y += 0.02
  cube.rotation.z += 0.02

  step+=0.04
  sphere.position.x = 20 + (10 * (Math.cos(step)))
  sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)))

  requestAnimationFrame(renderScene)
  renderer.render(scene, camera)
}

renderScene()